package net.guerlab.smart.wx.service.service.impl;

import net.guerlab.commons.number.NumberHelper;
import net.guerlab.smart.platform.server.service.BaseServiceImpl;
import net.guerlab.smart.wx.core.domain.WxMsgDataFormat;
import net.guerlab.smart.wx.core.enums.WxAppType;
import net.guerlab.smart.wx.core.exception.*;
import net.guerlab.smart.wx.core.utils.WxCpUtils;
import net.guerlab.smart.wx.service.entity.WxApp;
import net.guerlab.smart.wx.service.mapper.WxAppMapper;
import net.guerlab.smart.wx.service.service.AfterWxAppDeleteHandler;
import net.guerlab.smart.wx.service.service.AfterWxAppUpdateHandler;
import net.guerlab.smart.wx.service.service.WxAppService;
import net.guerlab.spring.commons.util.SpringApplicationContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 微信应用实现
 *
 * @author guer
 */
@Service
public class WxAppServiceImpl extends BaseServiceImpl<WxApp, String, WxAppMapper> implements WxAppService {

    @Override
    protected void insertBefore(WxApp entity) {
        String appId = StringUtils.trimToNull(entity.getAppId());
        String corpId = StringUtils.trimToNull(entity.getCorpId());
        Integer agentId = entity.getAgentId();
        String secret = StringUtils.trimToNull(entity.getSecret());
        String appName = StringUtils.trimToNull(entity.getAppName());
        WxMsgDataFormat msgDataFormat = entity.getMsgDataFormat();
        WxAppType appType = entity.getWxAppType();

        if (appType == WxAppType.CP) {
            if (corpId == null) {
                throw new CorpIdInvalidException();
            }
            if (!NumberHelper.greaterZero(agentId)) {
                throw new AgentIdInvalidException();
            }
            appId = WxCpUtils.buildAppId(corpId, agentId);
        } else {
            if (appId == null) {
                throw new AppIdInvalidException();
            }
            corpId = appId;
            agentId = WxApp.DEFAULT_AGENT_ID;
        }
        if (secret == null) {
            throw new SecretInvalidException();
        }
        if (appType == null) {
            throw new WxAppTypeInvalidException();
        }
        if (selectById(appId) != null) {
            throw new AppIdRepeatException();
        }

        LocalDateTime now = LocalDateTime.now();

        entity.setAppId(appId);
        entity.setCorpId(corpId);
        entity.setAgentId(agentId);
        entity.setSecret(secret);
        entity.setToken(StringUtils.trimToEmpty(entity.getToken()));
        entity.setAesKey(StringUtils.trimToEmpty(entity.getAesKey()));
        if (msgDataFormat == null || appType != WxAppType.MINI_APP) {
            entity.setMsgDataFormat(WxMsgDataFormat.XML);
        }
        entity.setAppName(appName != null ? appName : appId);
        if (entity.getEnable() == null) {
            entity.setEnable(true);
        }
        entity.setRemark(StringUtils.trimToEmpty(entity.getRemark()));
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
    }

    @Override
    protected void updateBefore(WxApp entity) {
        if (entity.getWxAppType() != WxAppType.MINI_APP) {
            entity.setMsgDataFormat(null);
        }
    }

    @Override
    protected void updateAfter(WxApp entity) {
        SpringApplicationContextUtil.getContext().getBeansOfType(AfterWxAppUpdateHandler.class).values()
                .forEach((handler) -> handler.afterWxAppUpdateHandler(entity));
    }

    @Override
    protected void deleteByIdAfter(String id, Boolean force) {
        SpringApplicationContextUtil.getContext().getBeansOfType(AfterWxAppDeleteHandler.class).values()
                .forEach((handler) -> handler.afterWxAppDeleteHandler(id));
    }

    @Override
    protected void deleteAfter(WxApp entity, Boolean force) {
        deleteByIdAfter(entity.getAppId(), force);
    }
}
